<template>
  <div id="kruup-container" :ref="refName">
    <template v-if="ready">
      <slot></slot>
    </template>
  </div>
</template>

<script>
import { ref, getCurrentInstance, onMounted, onUnmounted, nextTick,defineComponent } from "vue";
import { debounce } from "../../utils/index";
export default defineComponent({
  name: "KruupContainer",
  props: {
    options: Object, // 传入的宽高
  },
  setup(ctx) {
    // 宽高 换算  缩放  真实的宽高：body / 视口的高度
    const refName = "kruupContainer";
    const width = ref(0);
    const height = ref(0);
    const ready = ref(false);

    // 视口：屏幕 的宽高
    const originalWidth = ref(0);
    const originalHeight = ref(0);
    let context, dom, observer;

    // 根据  参数  和视口 计算 缩放比
    const initSize = () => {
      return new Promise((resolve) => {
        nextTick(() => {
          dom = context.$refs[refName]; //
          // 屏幕的真实 宽高
          if (ctx.options && ctx.options.width && ctx.options.height) {
            width.value = ctx.options.width;
            height.value = ctx.options.height;
          } else {
            // 获取 容器的 实际宽高  这个宽高 是根据内容撑起
            width.value = dom.clientWidth;
            width.height = dom.clineHeight;
          }

          // 视口是固定的 只需要初始化一次  画布的宽高  不是body的 实际可是区域的
          if (!originalWidth.value || !originalHeight.value) {
            originalWidth.value = window.screen.width;
            originalHeight.value = window.screen.height;
          }
          resolve();
        });
      });
    };

    // 更新 容器 宽高
    const updateSize = () => {
      if (width.value && height.value) {
        dom.style.width = `${width.value}px`;
        dom.style.height = `${height.value}px`;
      } else {
        // 视口
        dom.style.width = `${originalWidth.value}px`;
        dom.style.height = `${originalHeight.value}px`;
      }
    };

    // 计算压缩比例
    const uptateScale = () => {
      // 获取 真实的可视区域
      const currentWidth = document.body.clientWidth; // 实际可视区域的宽
      const currentHeight = document.body.clientHeight;
      // 获取 屏幕的最终 宽高
      const realWidth = width.value || originalWidth.value;
      const realHeight = height.value || originalHeight.value;
      const widthScale = currentWidth / realWidth;
      const heigthScale = currentHeight / realHeight;

      dom.style.transform = `scale(${widthScale},${heigthScale})`;
    };

    const onResize = async (e) => {
      await initSize();
      uptateScale();
    };
    const initMutationObserver = () => {
      const MutationObserver = window.MutationObserver;
      // style 变化是 出发 onResize
      observer = new MutationObserver(onResize);
      observer.observe(dom, {
        attributes: true,
        attributeFilter: ["style"], // 监听 style 的变化  
        attributeOldValue: true, // 是否需要 变更前的值
      });
    };

    const removeMutationObserver = () => {
      if (observer) {
        observer.disconnect();
        observer.takeRecords();
        observer = null;
      }
    };
    // 获取 实际内容高度
    onMounted(async () => {
      ready.value = false;
      context = getCurrentInstance().ctx;
      await initSize();
      updateSize();
      uptateScale();

      window.addEventListener("resize", debounce(300, onResize));
      initMutationObserver();
      ready.value = true;
    });
    onUnmounted(() => {
      window.removeEventListener("resize", onResize);
      removeMutationObserver();
    });

    return {
      refName,
      ready,
    };
  },
});
</script>

<style lang="scss" scoped>
#kruup-container {
  position: fixed;
  top: 0;
  left: 0;
  overflow: hidden;
  transform-origin: left top;
  z-index: 999;
}
</style>